#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

static pthread_mutex_t mtx_1=PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mtx_2=PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mtx_3=PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t cond_a=PTHREAD_COND_INITIALIZER;
static pthread_cond_t cond_b=PTHREAD_COND_INITIALIZER;
static pthread_cond_t cond_c=PTHREAD_COND_INITIALIZER;

static int times = 1000;
void *func_a(void *){
    int i = times;
    while(i--){
        pthread_mutex_lock(&mtx_1);
        pthread_cond_wait(&cond_c,&mtx_1);
        cout <<"A("<<i<<") ";
        usleep(1);
        pthread_mutex_unlock(&mtx_1);
        pthread_cond_signal(&cond_a);
    }
    pthread_exit(NULL);
}

void *func_b(void *){
    int i = times;
    while(i--){
        pthread_mutex_lock(&mtx_2);
        pthread_cond_wait(&cond_a,&mtx_2);
        cout <<"B("<<i<<") ";
        usleep(1);
        pthread_mutex_unlock(&mtx_2);
        pthread_cond_signal(&cond_b);
    }
    pthread_exit(NULL);
}

void *func_c(void *){
    int i = times;
    while(i--){
        pthread_mutex_lock(&mtx_3);
        pthread_cond_wait(&cond_b,&mtx_3);
        cout <<"C("<<i<<") "<<endl;
        usleep(1);
        pthread_mutex_unlock(&mtx_3);
        pthread_cond_signal(&cond_c);
    }
    pthread_exit(NULL);
}

int main(){

    pthread_t id1,id2,id3;
    pthread_create(&id1,NULL,func_a,NULL);
    pthread_create(&id2,NULL,func_b,NULL);
    pthread_create(&id3,NULL,func_c,NULL);

    cout << "signal : cond_c"<<endl;
    pthread_cond_signal(&cond_c);
    

    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    pthread_join(id3,NULL);

    return 0;
}